/*
 *  $Id: ParticlePoints.cs 1191 2010-11-12 16:17:29Z thenn.erannor $
 *  This file is a part of Ragima CCG.
 *  (C) 2008-2009 Ragima development group.
 *
 *  Licensed under the terms of the GNU GPL License version 2.
 *
 */
using System;
using System.Collections.Generic;

using AgateLib.Geometry;

using Ragima.Helper;

namespace Ragima.UI {
    /// <summary>
    /// Стандартные генераторы координат частиц.
    /// </summary>
    public static class ParticlePoints {
        public static IEnumerable<Point> Always(Point point) {
            while (true)
                yield return point;
        }

        public static IEnumerable<Point> Mouse() {
            while (true)
                yield return AgateLib.InputLib.Mouse.Position;
        }

        public static IEnumerable<Point> RandomByRect(Rectangle rect) {
            while (true) {
                int x = rect.X + Randomizer.Global.Next(rect.Width);
                int y = rect.Y + Randomizer.Global.Next(rect.Height);
                yield return new Point(x, y);
            }
        }

        public static IEnumerable<Point> AroundPoint(Point center, int radius) {
            while (true) {
                var point = new PolarPoint(Randomizer.Global.Next(360), radius);
                yield return point.ToPoint(center);
            }
        }

        public static IEnumerable<Point> AroundCenter(Rectangle param, int radius) {
            int x = param.X + param.Width / 2;
            int y = param.Y + param.Height / 2;
            return AroundPoint(new Point(x, y), radius);
        }

        public static IEnumerable<Point> TraceBorder(Rectangle rect) {
            int radnomLength = rect.Width * 2 + rect.Height * 2;
            while (true) {
                int genCoord = Randomizer.Global.Next(radnomLength);
                int v1 = rect.Width * 2 + rect.Height;
                int v2 = rect.Width * 2;
                int v3 = rect.Width;
                int x = rect.X;
                int y = rect.Y;
                if (genCoord > v1) {
                    y += genCoord - v1;
                } else if (genCoord > v2) {
                    x += rect.Width;
                    y += genCoord - v2;
                } else if (genCoord > v3) {
                    x += genCoord - v3;
                } else {
                    y += rect.Height;
                    x += genCoord;
                }
                yield return new Point(x, y);
            }
        }
        public static IEnumerable<Point> EngulfFromSide(Rectangle rect, int Part, int Side) {
            //  1 - верх, 2 - низ, 3 - лево, 4 - право
            while (true) {
                double rx = (Side > 2) ? Math.Sin(Randomizer.Global.Next(30) / 150) : 1;
                double lx = ((Side == 4) ? -1 : 1) * Randomizer.Global.Next(rect.Width / ((Side > 2) ? Part : 1));
                if (Side > 2)
                    rx = (rx < 0) ? rx / -2 : rx + 0.5;
                int x = rect.X + ((Side == 4) ? rect.Width : 0) + (int) Math.Ceiling(lx * rx);

                double ry = (Side < 3) ? Math.Sin(Randomizer.Global.Next(30) / 150) : 1;
                double ly = ((Side == 2) ? -1 : 1) * Randomizer.Global.Next(rect.Height / ((Side < 3) ? Part : 1));
                if (Side < 3)
                    ry = (ry < 0) ? ry / -2 : ry + 0.5;
                int y = rect.Y + ((Side == 2) ? rect.Height : 0) + (int) Math.Ceiling(ly * ry);

                yield return new Point(x, y);
            }
        }
        public static IEnumerable<Point> EngulfFromLeft(Rectangle rect, int Part) {
            return EngulfFromSide(rect, Part, 3);
        }
        public static IEnumerable<Point> EngulfFromRight(Rectangle rect, int Part) {
            return EngulfFromSide(rect, Part, 4);
        }
        public static IEnumerable<Point> EngulfFromBottom(Rectangle rect, int Part) {
            return EngulfFromSide(rect, Part, 2);
        }
        public static IEnumerable<Point> EngulfFromTop(Rectangle rect, int Part) {
            return EngulfFromSide(rect, Part, 1);
        }

        public static IEnumerable<Point> RandomByRegion(Region region) {
            return RandomByRect(region.Rect);
        }
    }
}
